#ifndef FND_GAME_2D_MESSAGEHANDLE_H_
#define FND_GAME_2D_MESSAGEHANDLE_H_
#include <map>
#include <cassert>
#include <stdexcept>
#include <boost/bind.hpp>
#include <boost/function.hpp>

namespace FndGame2D {
  template<typename Key, typename FuncParam>
    class message_handle {
      public:
        typedef message_handle<Key, FuncParam>   class_type ;
        typedef Key                             key_type ;
        typedef FuncParam                       function_para_type ;
        typedef FuncParam*                      function_para_pointer ;
      public:
        typedef boost::function<bool (const function_para_type&)> function_type ;
        typedef std::map<key_type, function_type > HandleMap ;

        bool add_handle(const key_type& k, function_type func) {
          return (handleMap.insert(std::make_pair(k, func))).second ;
        }
        template<typename T>
        bool add_handle(const key_type& k, T* obj,
            void(T::*func)(const function_para_type&)) {
          assert(obj) ;
          if(!obj) {
            throw std::runtime_error("pointer is not valid") ;
          }
          return this->add_handle(k, boost::bind(boost::mem_fn(func), obj, _1)) ;
        }

        bool handle_message(const key_type& k, const function_para_type& param) {
          typedef typename HandleMap::iterator iterator ;
          iterator action(handleMap.find(k)) ;
          if(action != handleMap.end()) {
           return (*action).second(param) ;
          }
	  return false ;
          
        }

        bool is_message_registered(const key_type& k) {
          return handleMap.find(k) != handleMap.end() ;
        }

        void remove_handle(const key_type& k) {
          handleMap.erase(k) ;
        }

      private:
        HandleMap handleMap ;
    } ;
}
#endif
